<?php
/**
 * Created by PhpStorm.
 * User: 86188
 * Date: 2020/12/2
 * Time: 18:51
 */

namespace app\admin\job;
use think\Log;
use think\queue\Job;
use think\Db;

use app\service\invoiceService;
use app\service\apiService;
use invoice\Api;
//直接开票
class BillParkInvoice
{
    /**
     * fire方法是消息队列默认调用的方法
     * @param Job            $job      当前的任务对象
     * @param array|mixed    $data     发布任务时自定义的数据
     */
    public function fire(Job $job,$data){


        // 如有必要,可以根据业务需求和数据库中的最新数据,判断该任务是否仍有必要执行.
        //执行发票开票

        $isJobDone = $this->doInvoiceJob($data);
        if ($job->attempts() > 3) {
            //通过这个方法可以检查这个任务已经重试了几次了
            print("<warn>Hello Job has been retried more than 3 times!"."</warn>\n");
            $job->delete();
            // 也可以重新发布这个任务
            //print("<info>Hello Job will be availabe again after 2s."."</info>\n");
            //$job->release(2); //$delay为延迟时间，表示该任务延迟2秒后再执行
        }
        if ($isJobDone) {
            //如果任务执行成功， 记得删除任务
            $job->delete();
            print("<info>Hello Job has been done and deleted"."</info>\n");
        }else{
            if ($job->attempts() > 3) {
                //通过这个方法可以检查这个任务已经重试了几次了
                print("<warn>Hello Job has been retried more than 3 times!"."</warn>\n");
                $job->delete();
                // 也可以重新发布这个任务
                //print("<info>Hello Job will be availabe again after 2s."."</info>\n");
                //$job->release(2); //$delay为延迟时间，表示该任务延迟2秒后再执行
            }
        }
    }
    public function doInvoiceJob($data){
        return true;
        $invoice=$this->invoiceCreate($data);
        if($invoice["errorCode"]=="0"){


            $data=$this->invoiceData($data["id"]);

            $api=new apiService();
            $res=$api->invoiceSendDirect(json_encode($data));

            print("<info>. job Data is: ".var_export($res,true)."</info> \n");
        }
    }

    public function invoiceData($id){

        $invoice=Db::table("parkgatebillorder")->where("id",$id)->find();




        $serviceinfo=(new invoiceService())->parkingInvoice($invoice["parkingNo"]);
        //return $serviceinfo;
        //var_dump($info);
        $data["m_short_name"]=$serviceinfo["m_short_name"];
        $data["sub_m_short_name"]=$serviceinfo["sub_m_short_name"];
        $data["user_id"]=$invoice["user_id"];


        $data["invoice_date"]=$invoice["invoice_date"];
        $data["sum_amount"]=$invoice["order_money"];
        $data["tax_amount"]=round(($invoice["order_money"]*$serviceinfo["taxrate"])/(1+$serviceinfo["taxrate"]),2);//合计税额，票面上的合计税额
        $data["ex_tax_amount"]=$data["sum_amount"]-$data["tax_amount"];//不含税金额
        $data["item_name"]="物业费";
        $data["item_no"]="1010101990000000000";
        $data["item_spec"]="G39";
        $data["item_unit"]="台";
        $data["item_quantity"]="1";
        $data["item_unit_price"]=$data["ex_tax_amount"];
        $data["item_ex_tax_amount"]=$data["ex_tax_amount"];
        $data["item_tax_amount"]=$data["tax_amount"];
        $data["item_sum_amount"]=$data["sum_amount"];
        $data["item_tax_rate"]=$serviceinfo["taxrate"];

        $data["out_trade_no"]=$invoice["out_trade_no"];
        $data["invoice_type"]='BLUE';
        $data["invoice_kind"]='PLAIN';

        $data["invoice_code"]=$invoice["invoiceCode"];//发票代码，该字段与invoice_no构成一张发票的唯一标识
        $data["invoice_no"]=$invoice["invoiceNum"];//发票号码，该字段与invoice_code构成一张发票的唯一标识。
        //购买方信息
        $data["title_name"]="个人";
        $data["payer_register_no"]="";//购方税号
        $data["payer_address_tel"]="";
        $data["payer_bank_name_account"]="";

        //销售方信息 根据停车场查询
        $data["payee_register_no"]=$serviceinfo["fp_saler_tax_num"];
        $data["payee_register_name"]=$serviceinfo["name"];
        $data["payee_address_tel"]=$serviceinfo["fp_saler_account"];

        $data["payee_bank_name_account"]=$serviceinfo["bank"];
        $data["check_code"]='';
        //$data["out_invoice_id"]=$info["orderNo"];
        $data["out_invoice_id"]=date("YmdHis").rand(100000,999999);
        $data["ori_blue_inv_code"]='';
        $data["ori_blue_inv_no"]='';
        $data["file_download_type"]='PDF';
        $data["file_download_url"]=$invoice["invoiceFileUrl"];
        $data["payee"]='';
        $data["checker"]='';
        $data["clerk"]='';
        $data["invoice_memo"]="停车费";
        $data["xtend_fields"]='';
        return $data;

    }

    //执行开票操作
    public function invoiceCreate($data){
        $id=$data["id"];
        $invoiceinfo=Db::table('parkgatebillorder')->find($id);
        if($invoiceinfo["invoice_type"]!="3"){
            $res=$this->checkEInvoice($data);
            return $res;
        }
        $serviceinfo=(new invoiceService())->parkingInvoice($invoiceinfo["parkingNo"]);
        //金额
        $money=$invoiceinfo["pay_money"];
        //税率
        $taxrate=$serviceinfo["taxrate"];
        //税额
        $tax=$taxrate*$money;

        $invoiceDetail= "{'goodsName':'车位费','num':'1','price':'{$money}','withTaxFlag':'1','taxRate':'{$taxrate}','tax':'{$tax}'}";

        $timestmp = time();
        $remark=$invoiceinfo["parkingName"]."-支付宝支付";
        //判断access_token是否到期
        $second = strtotime(date('Y-m-d H:i:s',time()))-strtotime($serviceinfo['fp_expires_in']);
        if($second <86400){
            //未过期
            $access_token = $serviceinfo['fp_access_token'];
        }else{
            //过期从新获取
            $res = (new invoiceService())->getToken($serviceinfo['service_id']);
            if(array_key_exists("error",$res)){
                $res["errorCode"]="1";
                $res["error"]= $res["error_description"];
                return $res;
            }
            $access_token = $res['fp_access_token'];
        }

        $webinfo=Db::table("webset")->where("id","1")->find();
        $appKey = $webinfo["appKey"];
        $appSecret = $webinfo["appSecret"];
        $token = $access_token;// please store the token and refresh it before expired
        $taxnum = $serviceinfo["fp_saler_tax_num"];

        $url = "https://sdk.nuonuo.com/open/v1/services"; // change to online domain
        $method = "nuonuo.electronInvoice.requestBilling"; // change to your method
        $senid = uniqid(); // generate your meaningful senid

        $invoiceDate = date('Y-m-d H:i:s',time());
        $orderNo = time().rand(100000,999999);
        $timestmp = time();

        $buyerName="个人";

        $buyerPhone=1;
        $buyerTaxNum=$invoiceinfo["buyerTaxnum"];
        $buyerTel=$invoiceinfo["buyerTel"];
        $buyerAddress=$invoiceinfo["buyerAddress"];
        $buyerAccount=$invoiceinfo["buyerAccount"];

        //$buyerPhone="188561510";
        $fp_saler_tax_num=$serviceinfo['fp_saler_tax_num'];
        $salerAddress=$serviceinfo['address'];
        $salerTel=$serviceinfo['phone'];
        $salerAddress=$serviceinfo['address'];
        $salerAccount=$serviceinfo['fp_saler_account'];
        $emt="";

        //var_dump($content);
        $body = "{
        \"order\": {
            \"buyerName\": \"$buyerName\",
            \"orderNo\": \"$orderNo\",
            \"buyerTaxNum\": \"$buyerTaxNum\",
            \"buyerTel\": \"$buyerTel\",
            \"buyerAddress\": \"$buyerAddress\",
            \"buyerAccount\": \"$buyerAccount\",
            \"invoiceDate\": \"$invoiceDate\",
            \"clerk\": \"\",
            \"salerTaxNum\": \"$fp_saler_tax_num\",
            \"salerTel\": \"$salerTel\",
            \"salerAddress\": \"$salerAddress\",
            \"salerAccount\": \"$salerAccount\",
            \"invoiceType\": \"1\",
            \"pushMode\": \"1\",
            \"buyerPhone\": \"$buyerPhone\",
            \"remark\": \"$remark\",
            \"invoiceDetail\": [$invoiceDetail],
            \"callBackUrl\": \"http://www.jfzhiwen.com/admin/invoice/callback/\"
            }
        }";

        $result = Api::sendPostSyncRequest($url, $senid, $appKey, $appSecret, $token, $taxnum, $method, $body);
        //var_dump($result);
        $result = json_decode($result, true);
        //Log::write($result,"invoiceresult");
        if($result['code'] == 'E0000'){
            $invoiceSerialNum = $result['result']['invoiceSerialNum'];
            $invoice["invoice_serial_num"] = $result['result']['invoiceSerialNum'];
            $invoice["invoice_time"]=date('Y-m-d H:i:s');
            $invoice["invoice_type"]="1";

            $invoice["invoice_date"]=date('Y-m-d');
            $res=Db::table('parkgatebillorder')->where('id', $id)->update($invoice);

            //查询开票信息
            $url_check = "https://sdk.nuonuo.com/open/v1/services"; // change to online domain
            $method_check = "nuonuo.electronInvoice.CheckEInvoice"; // change to your method
            $senid_check = uniqid(); // generate your meaningful senid
            $body_check = json_encode(
                array(
                    "invoiceSerialNum" => array($invoice['invoice_serial_num'])
                )
            );

            $result_check = Api::sendPostSyncRequest($url_check, $senid_check, $appKey, $appSecret, $token, $taxnum, $method_check, $body_check);
            $result_check = json_decode($result_check, true);

            if($result_check['code'] == 'E0000'){

                Db::table("parkgatebillorder")
                    ->where('id',$id)
                    ->update([
                        "invoiceFileUrl"=>$result_check['result'][0]['invoiceFileUrl'],
                        "invoiceNum"=>$result['result'][0]["invoiceNum"],
                        "invoiceCode"=>$result['result'][0]['invoiceCode']
                    ]);

                $res=Db::table("parkgatebillorder")->where('id',$id)->find();
                $res["errorCode"]="0";
                return $res;
            }else{
                $res["errorCode"]="1";
                $res["error"]= $result['describe'];
                return $res;
                return json(['error' => $result['describe']]);
            }
        }else{
            $res["errorCode"]="1";
            $res["error"]= $result['describe'];
            return $res;
        }
    }
    public function checkEInvoice($data){
        $id=$data["id"];

        $data=Db::table('parkgatebillorder')->find($id);

        if(!empty($data["invoiceFileUrl"])){
            $data["errorCode"]="0";
            return $data;

        }
        //根据商家id查询开票信息
        $serviceinfo=(new invoiceService())->parkingInvoice($data["parkingNo"]);

        //判断access_token是否到期
        $second = strtotime(date('Y-m-d H:i:s',time()))-strtotime($serviceinfo['fp_expires_in']);
        if($second <86400){
            //未过期
            $access_token = $serviceinfo['fp_access_token'];
        }else{
            //过期从新获取
            $res = (new invoiceService())->getToken($serviceinfo['service_id']);
            if(array_key_exists("error",$res)){
                return $res;
                return $res["error_description"];
            }
            $access_token = $res['fp_access_token'];
        }
        //var_dump($access_token);die;
        $timestmp = time();

        $webinfo=Db::table("webset")->where("id","1")->find();
        $appKey = $webinfo["appKey"];
        $appSecret = $webinfo["appSecret"];
        $token = $access_token;// please store the token and refresh it before expired
        $taxnum = $serviceinfo["fp_saler_tax_num"];

        $url = "https://sdk.nuonuo.com/open/v1/services"; // change to online domain
        $method = "nuonuo.electronInvoice.CheckEInvoice"; // change to your method
        $senid = uniqid(); // generate your meaningful senid
        $body = json_encode(
            array(
                "invoiceSerialNum" => array($data['invoice_serial_num'])
            )
        );

        $result = Api::sendPostSyncRequest($url, $senid, $appKey, $appSecret, $token, $taxnum, $method, $body);


        $result = json_decode($result, true);

        if($result['code'] == 'E0000'){
            //return $result['result'][0]['invoiceFileUrl'];
            Db::table("parkgatebillorder")
                ->where('id',$id)
                ->update([
                    "invoiceFileUrl"=>$result['result'][0]['invoiceFileUrl'],
                    "invoiceNum"=>$result['result'][0]["invoiceNum"],
                    "invoiceCode"=>$result['result'][0]['invoiceCode']
                ]);

            $res=Db::table("parkgatebillorder")->where('id',$id)->find();
            $res["errorCode"]="0";
            return $res;
        }else{
            $res["errorCode"]="1";
            $res["error"]= $result['describe'];
            return $res;
            return json(['error' => $result['describe']]);
        }
    }
    /**
     * 根据消息中的数据进行实际的业务处理
     * @param array|mixed    $data     发布任务时自定义的数据
     * @return boolean                 任务执行的结果
     */


    public function failed($data){
        file_put_contents("failed.txt","yang",FILE_APPEND);

    }
}